package spzx.service.impl;

import com.atguigu.spzx.model.dto.system.AssginMenuDto;
import com.atguigu.spzx.model.entity.system.SysMenu;
import com.atguigu.spzx.model.vo.system.SysMenuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import spzx.exception.SpzxException;
import spzx.mapper.SysMenuMapper;
import spzx.service.SysMenuService;
import utils.SysUserThreadLocal;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SysMenuServiceImpl  implements SysMenuService {


    @Autowired
    SysMenuMapper sysMenuMapper;

    //查询所有一级菜单和其下级子菜单
    @Override
    public List<SysMenu> findMenuListByParentId(Long parentId) {

        List<SysMenu> list = sysMenuMapper.findByParentId(parentId);


        //递归
        list.forEach(sysMenu -> {
            List<SysMenu> children = this.findMenuListByParentId(sysMenu.getId());//查询当前菜单的下级列表
            sysMenu.setChildren(children);
        });


        return list;
    }

    @Override
    public void save(SysMenu sysMenu) {
        sysMenuMapper.insert(sysMenu) ;
    }

    @Override
    public void deleteByMenuId(Long menuId) {
        //先判断当前菜单是否存在下级
        List<SysMenu> children = sysMenuMapper.findByParentId(menuId);
        if(children!=null && children.size()>0){
            throw new SpzxException(501,"当前菜单存在下级，不允许删除");
        }
        sysMenuMapper.deleteByMenuId(menuId);
    }

    @Override
    public List<Long> findMenuIdListByRoleId(Long roleId) {
        return sysMenuMapper.findMenuIdListByRoleId(roleId);
    }

    @Transactional
    @Override
    public void sysMenuService(AssginMenuDto assginMenuDto) {
        //1、从角色菜单关系表中根据角色id删除
        sysMenuMapper.deleteRoleMenu(assginMenuDto.getRoleId());
        //2、重新建立关系数据
        Long roleId = assginMenuDto.getRoleId();
        List<Map<String, Number>> menuIdList = assginMenuDto.getMenuIdList();
        for (Map<String, Number> map : menuIdList) {
            //{menuId:item.id , isHalf:0}
            Number menuId = map.get("menuId");
            Number isHalf = map.get("isHalf");

            sysMenuMapper.addRoleMenu(roleId,menuId,isHalf);
        }
    }

    @Override
    public List<SysMenuVo> findCurrentUserMenuList() {
        //查询当前用户的所有的一级菜单和其下级子菜单
        List<SysMenu> list = this.findCurrentUserMenuList(SysUserThreadLocal.getSysUser().getId(),0L);
        return this.sysMenuListToSysMenuVoList(list);
    }

    /**
     * 上述接口实现类拓展出来的实现方法：进行泛型的转换: SysMenuList -> SysMenuVoList
     * @param list
     * @return
     */
    private List<SysMenuVo> sysMenuListToSysMenuVoList(List<SysMenu> list) {
        List<SysMenuVo> sysMenuVoList = new ArrayList<>();
        for (SysMenu sysMenu : list) {
            SysMenuVo sysMenuVo = new SysMenuVo();

            sysMenuVo.setTitle(sysMenu.getTitle());
            sysMenuVo.setName(sysMenu.getComponent());

            List<SysMenu> children = sysMenu.getChildren();
            if (children!= null && children.size() > 0) {
                sysMenuVo.setChildren(this.sysMenuListToSysMenuVoList(children));
            }

            sysMenuVoList.add(sysMenuVo);
        }
        return sysMenuVoList;
    }

    private List<SysMenu> findCurrentUserMenuList(Long userId,Long parentId) {
        List<SysMenu> list = sysMenuMapper.findByUserIdAndParentId(userId, parentId);
        //此处遍历菜单列表，递归查询其下级菜单
        for (SysMenu sysMenu : list) {
            Long id = sysMenu.getId();
            List<SysMenu> children = this.findCurrentUserMenuList(userId, id);
            sysMenu.setChildren(children);
        }
        return list;
    }
}

